module namespace gdata = "http://fgeorges.org/ns/google/data";

declare namespace xsl = "http://www.w3.org/1999/XSL/Transform";
declare namespace xs = "http://www.w3.org/2001/XMLSchema";
declare namespace doc = "http://www.CraneSoftwrights.com/ns/xslstyle";
declare namespace atom = "http://www.w3.org/2005/Atom";
declare namespace os = "http://a9.com/-/spec/opensearch/1.1/";
declare namespace http = "http://expath.org/ns/http-client";
declare namespace impl = "urn:X-FGeorges:xslt:google:data:impl";
declare namespace x2x = "TODO-xslt-to-xquery";

import module "http://expath.org/ns/http-client";
import module "urn:X-FGeorges:xslt:google:data:impl" at "gdata-impl.xq";
declare function gdata:encode-params($uri-path as xs:string, $params as element(gdata:param)*) as xs:string
{
 (), let $categories as element(gdata:param)* := (            $params[@name eq 'category'] )
   return (
       (),  (),            string-join(             (               $uri-path,               if ( exists($categories) ) then                 ('/-', $categories/concat('/', @value))               else                 (),               for $p in $params except $categories                 return (                   if ( position() eq 1 ) then '?' else '&amp;',                   (: @name should not need to be encoded, but that could                      prevent some kind of 'injection' if @name is not                      correct... :)                   encode-for-uri(@name), '=', encode-for-uri(@value)                 )             ),             ''           )         ,  ()   )
};
declare function gdata:make-service($service as xs:string, $email as xs:string, $pwd as xs:string) as element(gdata:service)
{
 (),  (), let $full-email := (            if ( contains($email, '@') ) then             $email           else             concat($email, '@gmail.com') )
   return (
       (),  (), let $auth-request as element(http:request) := (  (), element http:request { attribute method { 'post' } , attribute href { '{ $impl:auth-endpoint }' } ,  (), element http:header { attribute name { 'GData-Version' } , attribute value { '2' }  } ,  (), element http:body { attribute content-type { 'application/x-www-form-urlencoded' } ,  (), text { 'Email=' } ,  (), text { encode-for-uri($full-email) } ,  (), text { '&amp;Passwd=' } ,  (), text { encode-for-uri($pwd) } ,  (), text { '&amp;source=' } ,  (), text { encode-for-uri($impl:app-name) } ,  (), text { '&amp;service=' } ,  (), text { encode-for-uri($service) } ,  (), text { '&amp;accountType=' } ,  (), text {                     if ( ends-with($full-email, '@gmail.com') ) then                      'GOOGLE'                    else                      'HOSTED_OR_GOOGLE' } ,  () } ,  () } ,  () )
   return (
       (),  (), let $auth-token as xs:string := (  (),  (), let $r := ( http:send-request($auth-request) )
   return (
       (),  (),  if ( count($r) ne 2 ) then (  (), gdata:error('HTTPCL001'),  () ) else () ,  (),  if ( not($r[2] instance of xs:string) ) then (  (), gdata:error('HTTPCL002', $r[1]/http:body/@content-type),  () ) else () ,  (),  if ( xs:integer($r[1]/@status) ne 200 ) then (  (), gdata:error('HTTPCL003', $r[1]/@status, $r[1]/@message),  () ) else () ,  (),  (),               substring-after(                tokenize($r[2], '
')[starts-with(., 'Auth=')],                '='),  ()   )
 )
   return (
       (),  (), element gdata:service { attribute name { '{ $service }' } ,  (), element gdata:user { attribute escaped { '{ encode-for-uri($full-email) }' } ,  (), text { $full-email } ,  () } ,  (), element gdata:auth-token {  (), text { $auth-token } ,  () } ,  () } ,  ()   )
   )
   )
};
declare function gdata:get-entry($service as element(gdata:service), $entry-uri as xs:string) as element(atom:entry)
{
 (),  (), impl:get-stuff($service, $entry-uri, (), ()),  ()};
declare function gdata:get-entry($service as element(gdata:service), $entry-uri as xs:string, $params as element(gdata:param)*) as element(atom:entry)
{
 (),  (), impl:get-stuff($service, $entry-uri, $params, ()),  ()};
declare function gdata:get-entry($service as element(gdata:service), $entry-uri as xs:string, $params as element(gdata:param)*, $since as item()) as element(atom:entry)?
{
 (),  (), impl:get-stuff($service, $entry-uri, $params, $since),  ()};
declare function gdata:get-feed($service as element(gdata:service), $feed-uri as xs:string) as element(atom:feed)
{
 (),  (), impl:get-stuff($service, $feed-uri, (), ()),  ()};
declare function gdata:get-feed($service as element(gdata:service), $feed-uri as xs:string, $params as element(gdata:param)*) as element(atom:feed)
{
 (),  (), impl:get-stuff($service, $feed-uri, $params, ()),  ()};
declare function gdata:get-feed($service as element(gdata:service), $feed-uri as xs:string, $params as element(gdata:param)*, $since as item()) as element(atom:feed)
{
 (),  (), impl:get-stuff($service, $feed-uri, $params, $since),  ()};
declare function gdata:get-all-feeds($service as element(gdata:service), $feed-uri as xs:string) as element(atom:feed)+
{
 (),  (), gdata:get-all-feeds($service, $feed-uri, ()),  ()};
declare function gdata:get-all-feeds($service as element(gdata:service), $feed-uri as xs:string, $params as element(gdata:param)*) as element(atom:feed)+
{
 (),  (), let $start as xs:integer := (            ( $params[@name eq 'start-index']/@value, 1 )[1] )
   return (
       (),  (), let $max as xs:integer := (            ( $params[@name eq 'max-results']/@value, 25 )[1] )
   return (
       (), let $new-params as element(gdata:param)+ := (  (), $params[not(@name eq 'start-index')],  (),  if ( empty($params[@name eq 'max-results']) ) then (  (), element gdata:param { attribute name { 'max-results' } , attribute value { '{ $max }' }  } ,  () ) else () ,  () )
   return (
       (),            impl:get-all-feeds($service, $feed-uri, $start, $max, $new-params),  ()   )
   )
   )
};
declare variable $gdata:errors as element(e)+ := (  (), element e { attribute code { 'HTTPCL001' } ,  text { 'Authentication: wrong HTTP response.' } } ,  (), element e { attribute code { 'HTTPCL002' } ,  text { 'Authentication: return is not text but ''' }, element arg { attribute pos { '1' }  } ,  text { '''.' } } ,  (), element e { attribute code { 'HTTPCL003' } ,  text { 'Authentication: HTTP server returned error ''' }, element arg { attribute pos { '1' }  } ,  text { ' - ' }, element arg { attribute pos { '2' }  } ,  text { '''.' } } ,  (), element e { attribute code { 'HTTPCL004' } ,  text { 'Get atom element: wrong HTTP response.' } } ,  (), element e { attribute code { 'HTTPCL005' } ,  text { 'Get atom element: return is not XML but ''' }, element arg { attribute pos { '1' }  } ,  text { '''.' } } ,  (), element e { attribute code { 'HTTPCL006' } ,  text { 'Get atom element: HTTP server returned error ''' }, element arg { attribute pos { '1' }  } ,  text { ' - ' }, element arg { attribute pos { '2' }  } ,  text { '''.' } } ,  (), element e { attribute code { 'HTTPCL007' } ,  text { 'Not implemented yet.' } } ,  (), element e { attribute code { 'HTTPCL008' } ,  text { 'gdata:get-entry-since: wrong entry selector type.' } } ,  () );
declare function gdata:error($code as xs:string)
{
 (),  (),  ()};
declare function gdata:error($code as xs:string, $arg-1 as xs:string)
{
 (),  (),  ()};
declare function gdata:error($code as xs:string, $arg-1 as xs:string, $arg-2 as xs:string)
{
 (),  (),  ()};
